﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Backend.DAL;
using Backend.DTO;

namespace Backend.BLL
{
    public class UserBLL
    {
        private UserDAL userDAL = new UserDAL();

        public List<UserDTO> GetAllUser()
        {
            List<UserDTO> listOfUsers = new List<UserDTO>();

            try
            {
                listOfUsers = userDAL.GetAllUser();
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return listOfUsers;
        }

        public List<UserDTO> GetAllUser(string userType)
        {
            List<UserDTO> listOfUsers = new List<UserDTO>();

            try
            {
                listOfUsers = userDAL.GetAllUser(userType);
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return listOfUsers;
        }

        public List<UserDTO> GetAllUser(string userType, int excludeUserId)
        {
            List<UserDTO> listOfUsers = new List<UserDTO>();

            try
            {
                listOfUsers = userDAL.GetAllUser(userType, excludeUserId);
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return listOfUsers;
        }

        public UserDTO GetUser(string loginId)
        {
            UserDTO userDTO = null;

            try
            {
                userDTO = userDAL.GetUser(loginId);

                if (userDTO == null)
                {
                    throw new ApplicationException("Invalid user.");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return userDTO;
        }

        public UserDTO GetUserById(int id)
        {
            try
            {
                return userDAL.GetUserById(id);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public UserDTO GetUserByEmail(string email)
        {
            UserDTO userDTO = null;

            try
            {
                userDTO = userDAL.GetUserByEmail(email);

                if (userDTO == null)
                {
                    throw new ApplicationException("Invalid user email.");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return userDTO;
        }

        public UserDTO GetUserByResetKey(string key)
        {
            UserDTO userDTO = null;

            try
            {
                userDTO = userDAL.GetUserByResetKey(key);
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return userDTO;
        }

        public string AddUser(UserDTO aUser)
        {
            /* validate business logic */
            if (userDAL.IsLoginIdExist(aUser.LoginId))
            {
                return "Login Id already taken by another user. Please try a different one.";
            }

            if (userDAL.IsEmailExist(aUser.Email))
            {
                return "Email Address already exists";
            }

            try
            {
                return userDAL.AddUser(aUser);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public bool UpdateUser(string field, string value, int id)
        {
            try
            {
                return userDAL.UpdateUser(field, value, id);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void DeleteUser(int deleteId)
        {
            try
            {
                userDAL.DeleteUser(deleteId);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public bool IsEmailExist(string emailAddress)
        {
            try
            {
                return userDAL.IsEmailExist(emailAddress);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Reset User Password does the following.
        ///   * get user by email address [if not found then invalid email address]
        ///   * clear Password field
        ///   * generate a ResetPasswordKey [Guid]
        ///   * send an email to the 'Email' address providing a link to the ResetPassword page using the ResetPasswordKey
        /// </summary>
        /// <returns></returns>
        public string ResetPassword(string email)
        {
            string resetPasswordKey = Guid.NewGuid().ToString("N");

            try
            {
                UserDTO aUser = GetUserByEmail(email);

                if (aUser != null && aUser.IsActive)
                {
                    UpdateUser("ResetPasswordKey", resetPasswordKey, aUser.Id);
                    UpdateUser("Password", string.Empty, aUser.Id);

                    // send an email to user email id

                    return "success";
                }
                else
                {
                    return "Invalid user.";
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        public bool ChangePassword(UserDTO aUser, string newPassword)
        {
            try
            {
                UpdateUser("Password", newPassword, aUser.Id);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
